<template>
    <div>
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>权限管理</el-breadcrumb-item>
            <el-breadcrumb-item>角色列表</el-breadcrumb-item>
        </el-breadcrumb>
        <el-card>
            <el-row>
                <el-col>
                    <el-button type="primary">添加角色</el-button>
                </el-col>
            </el-row>
            <el-table :data="roleList" border stripe>
                <el-table-column type="expand">
                    <template slot-scope="scope">
                        <el-row v-for="(item, index) in scope.row.children" :key="item.id" :class="['bb', index === 0 ? 'bt' : '', 'vcenter']">
                            <el-col :span="6">
                                <el-tag closable @close="removeRoleById(scope.row, item.id)">{{ item.authName }}</el-tag>
                                <i class="el-icon-caret-right"></i>
                            </el-col>
                            <el-col :span="18">
                                <el-row v-for="(item2, index2) in item.children" :key="item2.id" :class="[index2 > 0 ? 'bt' : '', 'vcenter']">
                                    <el-col :span="5">
                                        <el-tag type="success" closable @close="removeRoleById(scope.row, item2.id)">{{ item2.authName }}</el-tag>
                                        <i class="el-icon-caret-right"></i>
                                    </el-col>
                                    <el-col :span="19">
                                        <el-tag type="warning" v-for="item3 in item2.children" :key="item3.id" closable @close="removeRoleById(scope.row, item3.id)">{{ item3.authName }}</el-tag>
                                    </el-col>
                                </el-row>
                            </el-col>
                        </el-row>
                    </template>
                </el-table-column>
                <el-table-column label="#" type="index"></el-table-column>
                <el-table-column label="角色名称" prop="roleName"></el-table-column>
                <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
                <el-table-column label="操作">
                    <template slot-scope="scope">
                        <el-button type="primary" icon="el-icon-edit" size="mini">编辑</el-button>
                        <el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
                        <el-button type="warning" icon="el-icon-setting" size="mini" @click="showRightDialogVisible(scope.row)">分配权限</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>
        <!-- 对话框 -->
        <el-dialog title="分配角色" :visible.sync="rightDialogVisible" width="40%" @close="rightDialogClosed">
            <el-tree :data="rightList" :props="treeProps" node-key="id" show-checkbox default-expand-all :default-checked-keys="defKeys" ref="treeRef"></el-tree>
            <span slot="footer" class="dialog-footer">
                <el-button @click="rightDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="allotRights">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
export default {
    data() {
        return {
            roleList: [], // 角色列表
            rightDialogVisible: false, // 分配权限的对话框
            rightList: [], // 所有权限列表
            // 树形控件的属性绑定对象
            treeProps: {
                children: 'children', // 子级
                label: 'authName' // 显示的内容
            },
            defKeys: [], // 默认选中的节点数组
            roleId: '' // 角色 id
        }
    },
    created() {
        this.getRoleList();
    },
    methods: {
        async getRoleList() {
            const { data: res } = await this.$http.get('roles');

            if(res.meta.status !== 200) {
                return this.$message.error(res.meta.msg);
            }

            this.roleList = res.data;
            console.log(res);
        },
        // 根据 id 删除角色
        async removeRoleById(role, rightId) {
            const confirmResult = await this.$confirm('是否取消此角色的该权限？', '提示', {
                confirmButtonText: '确认',
                cancelButtonText: '取消'
            }).catch(err => err);

            if(confirmResult !== 'confirm') {
                return this.$message.info('取消删除');
            }

            const { data: res } = await this.$http.delete(`roles/${role.id}/rights/${rightId}`);

            if(res.meta.status !== 200) {
                return this.$message.error(res.meta.msg);
            }

            this.$message.success(res.meta.msg);
            role.children = res.data;
        },
        // 显示对话框
        showRightDialogVisible(role) {
            this.roleId = role.id;

            this.getRightList();
            this.getDefKeys(role, this.defKeys);

            this.rightDialogVisible = true;
        },
        // 获取所有权限
        async getRightList() {
            const { data: res } = await this.$http.get('rights/tree');

            if(res.meta.status !== 200) {
                return this.$message.error(res.meta.msg);
            }

            this.$message.success(res.meta.msg);
            this.rightList = res.data;
        },
        // 递归获取所有角色下的三级权限的 id，并且保存到 defKeys 数组中
        getDefKeys(node, arr) {
            if(!node.children) {
                return arr.push(node.id);
            }

            node.children.forEach(item => this.getDefKeys(item, arr));
        },
        // 监听对话框关闭
        rightDialogClosed() {
            this.defKeys = [];
        },
        // 修改权限
        async allotRights() {
            const keys = [
                ...this.$refs.treeRef.getCheckedKeys(),
                ...this.$refs.treeRef.getHalfCheckedKeys()
            ];

            const idStr = keys.join(',');

            const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, { rids: idStr });

            if(res.meta.status !== 200) {
                return this.$message.error(res.meta.msg);
            }

            this.$message.success(res.meta.msg);
            this.getRoleList();
            this.rightDialogClosed = false;
        }
    }
}
</script>

<style lang="less">
.el-tag {
    margin: 5px;
}
.bt {
    border-top: 1px solid #eee;
}
.bb {
    border-bottom: 1px solid #eee;
}
.vcenter {
    display: flex;
    align-items: center;
}
</style>